<template>
  <div class="page-demo">
    <div class="page-demo-top">
      <RadioGroup v-model="gameId" type="button" size="large">
        <Radio v-for="(val, key) in GameId" :label="val" :key="key">{{key}}</Radio>
      </RadioGroup>
    </div>
    <Divider>实时数据</Divider>
    <div class="page-demo-data">
      <template v-if="gameId === GameId.Dota2">
        <Card :dis-hover="true" class="game-info" v-for="(game, gameId) in gameMap" :key="gameId">
          <p slot="title">{{`${game.league.name} BO${game.round} 第${game.match.game_no}局`}}</p>
          <table cellspacing="0">
            <thead>
            <tr>
              <th style="width: 20%">队伍</th>
              <th style="width: 10%">比分</th>
              <th style="width: 10%">阵营</th>
              <th style="width: 15%">经济</th>
              <th style="width: 15%">剩余塔数</th>
              <th style="width: 10%">破路</th>
              <th style="width: 20%">阵容</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="team in getTeams(game)" :key="team.id">
              <td class="team">
                <img :src="team.logo" />
                {{team.tag}}
              </td>
              <td class="score">{{team.score}}</td>
              <td class="camp">{{team.radiant ? '天辉' : '夜魇'}}</td>
              <td class="score">{{team.gold}}</td>
              <td class="tower">{{team.tower_count}}</td>
              <td class="destroy">
                <template v-if="team.destroy_line_count !== undefined">
                  {{team.destroy_line_count}}/3
                </template>
              </td>
              <td class="ban">{{team.picks && team.picks.join(', ')}}</td>
            </tr>
            </tbody>
          </table>
        </Card>
      </template>

      <template v-if="gameId === GameId.CSGO">
        <!-- todo codes -->
      </template>
    </div>
  </div>
</template>

<script>
  import _ from 'lodash'
  import * as api from '@/api'
  import { GameId } from '@/const'

  export default {
    name: 'demo',
    data () {
      return {
        GameId,

        gameId: GameId.Dota2,
        ws: null,
        gameMap: {}
      }
    },
    watch: {
      gameId () {
        this.onSwitchGame()
      }
    },
    mounted () {
      api.setToken('5_t3xVKbhXbWxjhzg573pSNJz6KrO8o2GI2NangU')
      this.onSwitchGame()
      this.initWebSocket()
    },
    beforeDestroy () {
      this.destroyWebSocket()
    },
    methods: {
      async onSwitchGame () {
        let [result, err] = await api.lives(this.gameId)
        if (err) return

        result.data.forEach(game => {
          this.$set(this.gameMap, game.id, game)
        })
        console.log('gameMap', this.gameMap)
      },
      initWebSocket () {
        this.ws = new WebSocket('ws://sockets.1hole.cn/ws/dota2?key=WYBpjNRdCjjcHGQXKhzd8gHI5xGyKnlHW58iFe3F')
        this.ws.onmessage = event => {
          this.onMsg(JSON.parse(event.data))
        }
        this.ws.onclose = () => {
          this.ws = null
          this.initWebSocket()
        }
      },
      destroyWebSocket () {
        if (!this.ws) return
        this.ws.onclose = null
        this.ws.close()
      },
      onMsg (msg) {
        if (!this.gameMap.hasOwnProperty(msg.id)) return
        if (!msg.matches || msg.matches.length === 0) return
        this.gameMap[msg.id].match = _.last(msg.matches).data
        console.log('update', msg.id, Object.assign({}, this.gameMap[msg.id].match))
      },
      getTeams (game) {
        const getTeam = prefix => {
          let keys = Object.keys(game.match).filter(key => key.startsWith(prefix))
          let team = keys.reduce((obj, key) => {
            obj[key.slice(prefix.length)] = game.match[key]
            return obj
          }, {})
          Object.assign(team, game[prefix + 'team'])
          return team
        }

        const left = getTeam('left_')
        const right = getTeam('right_')
        right.radiant = !left.radiant
        let direTeam = left.radiant ? right : left
        let radiantTeam = left.radiant ? left : right
        Object.assign(direTeam, getTeam('dire_'))
        Object.assign(radiantTeam, getTeam('radiant_'))
        console.log('radiant_', getTeam('radiant_'))

        ;[left, right].forEach(team => {
          team.tower_state = this.statusNumberToMap(team.tower_state, ['top1', 'top2', 'top3', 'center1', 'center2', 'center3', 'bottom1', 'bottom2', 'bottom3', 'relicTop', 'relicBottom'])
          if (team.tower_state) {
            // 剩余塔数计算
            team.tower_count = Object.keys(team.tower_state).reduce((amount, key) => {
              if (team.tower_state[key]) amount++
              return amount
            }, 0)
          }

          team.barracks_state = this.statusNumberToMap(team.barracks_state, ['top1', 'top2', 'center1', 'center2', 'bottom1', 'bottom2'])
          if (team.barracks_state) {
            // 破路计算
            team.destroy_line_count = 0
            if (!team.barracks_state['top1'] && !team.barracks_state['top2']) team.destroy_line_count++
            if (!team.barracks_state['center1'] && !team.barracks_state['center2']) team.destroy_line_count++
            if (!team.barracks_state['bottom1'] && !team.barracks_state['bottom2']) team.destroy_line_count++
          }
        })

        console.log('teams', left, right)
        return [left, right]
      },
      statusNumberToMap (status, keys) {
        if (status === undefined) return null
        status = Number(status)
        let map = {}
        for (let i = 0; i < keys.length; i++) {
          let bit = 1 << i
          map[keys[i]] = (status & bit) > 0
        }
        return map
      }
    }
  }
</script>

<style lang="scss" scoped>
  .page-demo {
    width: 1024px;
    margin: 0 auto;
    padding: 16px 0;

    &-top {
      display: flex;
      justify-content: center;
    }
  }

  .game-info {
    margin: 16px 0;

    table {
      width: 100%;

      thead {
        color: #888;
      }

      tr {
        line-height: 32px;
      }

      th {
        font-weight: normal;

        &:first-child {
          text-align: left;
        }
      }

      td {
        text-align: center;
      }
    }

    .team {
      display: flex;
      align-items: center;

      img {
        width: 24px;
        height: 24px;
        margin-right: 16px;
      }
    }
  }
</style>
